package com.zlyx.easy.redis.config;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;

import com.zlyx.easy.asyn.annotations.MsgCustomer;
import com.zlyx.easy.asyn.interfaces.AsynMsgCustomer;
import com.zlyx.easy.asyn.supports.AbstractMsgListener;
import com.zlyx.easy.asyn.supports.AsynMsgSender;
import com.zlyx.easy.core.beans.AbstractBean;
import com.zlyx.easy.core.tool.Ops;
import com.zlyx.easy.core.utils.ProxyUtils;
import com.zlyx.easy.redis.supports.RedisMsgListener;
import com.zlyx.easy.redis.supports.RedisMsgSender;
import com.zlyx.easy.redis.utils.RedisUtils;

@Configuration
public class RedisConfig extends AbstractBean<MessageListener> {

	@Autowired(required = false)
	private RedisMsgListener listener;

	@Bean
	@ConditionalOnClass(RedisMessageListenerContainer.class)
	public RedisMessageListenerContainer redisMessageListenerContainer() throws Exception {
		RedisMessageListenerContainer container = new RedisMessageListenerContainer();
		container.addMessageListener(listener, new ChannelTopic(RedisUtils.DEFAULT_CHANNEL));
		List<MessageListener> listeners = getBeans();
		if (Ops.isNotNull(listeners)) {
			container.setConnectionFactory(RedisUtils.getConnectionFactory());
			for (MessageListener listener : listeners) {
				listener = (MessageListener) ProxyUtils.getTarget(listener);
				MsgCustomer annotation = listener.getClass().getAnnotation(MsgCustomer.class);
				if (annotation != null) {
					String[] channels = annotation.channels();
					if (channels != null && channels.length > 0) {
						for (String channel : channels) {
							container.addMessageListener(listener, new ChannelTopic(channel));
						}
					}
				}
			}
		}
		return container;
	}

	@Bean
	@ConditionalOnBean(AsynMsgCustomer.class)
	@ConditionalOnMissingBean(AbstractMsgListener.class)
	public AbstractMsgListener configRedisMsgListener() {
		return new RedisMsgListener();
	}

	@Bean
	@ConditionalOnClass(StringRedisTemplate.class)
	public AsynMsgSender configMsgSender() {
		return new RedisMsgSender();
	}

}
